package com.libui.webview.jsinterface

import android.webkit.ValueCallback
import com.libui.webview.WebViewEx

interface WebViewHandlerInterface {

    val id: String

    fun handle(webView: WebViewEx?, params: Map<String, Any>?)

    fun runSuccessCallback(
        webView: WebViewEx,
        uuid: String,
        code: Int,
        message: String,
        data: String?,
        handlerParams: Map<String, Any>,
        completion: ValueCallback<String?>? = null
    ) {
        runCallback(
            webView, "success",
            uuid, code, message, data,
            handlerParams, completion
        )

        runCompleteCallback(webView, uuid, handlerParams)
    }

    fun runFailCallback(
        webView: WebViewEx,
        uuid: String,
        code: Int,
        message: String,
        data: String?,
        handlerParams: Map<String, Any>,
        completion: ValueCallback<String?>? = null
    ) {
        runCallback(
            webView, "fail",
            uuid, code, message, data,
            handlerParams, completion
        )

        runCompleteCallback(webView, uuid, handlerParams)
    }

    private fun runCompleteCallback(
        webView: WebViewEx,
        uuid: String,
        handlerParams: Map<String, Any>,
        completion: ValueCallback<String?>? = null
    ) {
        val callbackMethodName = handlerParams["complete"] as? String
        if (callbackMethodName == null) {
            completion?.onReceiveValue(null)
            return
        }

        val js = """$callbackMethodName("$uuid")"""
        webView.evaluateJavascriptInMainThread(js) { value ->
            completion?.onReceiveValue(value)
        }
    }

    private fun runCallback(
        webView: WebViewEx,
        callbackMethod: String,
        uuid: String,
        code: Int,
        message: String,
        data: String?,
        handlerParams: Map<String, Any>,
        completion: ValueCallback<String?>? = null
    ) {
        val callbackMethodName = handlerParams[callbackMethod] as? String
        if (callbackMethodName == null) {
            completion?.onReceiveValue(null)
            return
        }

        val js = """$callbackMethodName("$uuid", $code, "$message", ${data ?: "null"})"""
        webView.evaluateJavascriptInMainThread(js) { value ->
            completion?.onReceiveValue(value)
        }
    }
}